package com.eastfair.imaster.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.auth.api.AuthServiceFeign;
import com.eastfair.auth.api.UserAccountServiceFeign;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.cache.operations.SuggestCacheKeyBuilder;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.core.utils.StringUtils;
import com.eastfair.imaster.dao.SuggestMapper;
import com.eastfair.imaster.dto.SuggestDTO;
import com.eastfair.imaster.dto.SuggestPageQuery;
import com.eastfair.imaster.entity.Suggest;
import com.eastfair.imaster.service.SuggestService;
import com.eastfair.imaster.vo.SuggestVO;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.eastfair.core.base.R.SUCCESS_CODE;

/**
 * <p>
 * 业务实现类
 *
 * </p>
 *
 * @author zjn
 * @date 2021-08-31
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class SuggestServiceImpl extends SuperCacheServiceImpl<SuggestMapper, Suggest> implements SuggestService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;
    @Autowired
    private AuthServiceFeign authServiceFeign;

    @Autowired
    private UserAccountServiceFeign userAccountServiceFeign;

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new SuggestCacheKeyBuilder();
    }

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(Suggest entity) {
        UpdateWrapper<Suggest> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(Suggest::getProjectId, entity.getProjectId()).eq(Suggest::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(Suggest model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(ContextUtil.getProjectId()));
        model.setProjectId(ContextUtil.getProjectId());
        return R.successDef();
    }

    @Override
    public Boolean save(SuggestDTO suggestDTO) {
        if (StringUtils.isBlank(suggestDTO.getContent())) {
            throw new NullPointerException("content is null");
        }

        Suggest suggest = BeanUtil.copyProperties(suggestDTO, Suggest.class);
        suggest.setUserId(ContextUtil.getUserId());
        suggest.setSubjectType(ContextUtil.getSubjectType());

        return save(suggest);
    }

    @Override
    public Boolean replyById(SuggestDTO suggestDTO) {
        if (StringUtils.isBlank(suggestDTO.getReplyContent()) || null == suggestDTO.getId()) {
            throw new NullPointerException("error params");
        }
        Suggest suggest = BeanUtil.copyProperties(suggestDTO, Suggest.class);
        suggest.setReplyTime(LocalDateTime.now());
        return updateByIdOfShard(suggest);
    }

    @Override
    public SuggestVO queryById(Long id) {
        QueryWrapper<Suggest> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Suggest::getProjectId, ContextUtil.getProjectId()).eq(Suggest::getId, id)
                .eq(Suggest::getIsDeleted, BusinessConstant.DELETE_NO).eq(Suggest::getIsEnabled, BusinessConstant.ENABLE_YES);
        Suggest suggest = getOne(queryWrapper);
        if (suggest == null) {
            return null;
        }
        return BeanUtil.copyProperties(suggest, SuggestVO.class);
    }

    @Override
    public Page<SuggestVO> queryPageList(PageParams<SuggestPageQuery> params) {
        QueryWrapper<Suggest> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Suggest::getProjectId, ContextUtil.getProjectId())
                .eq(Suggest::getIsDeleted, BusinessConstant.DELETE_NO).eq(Suggest::getIsEnabled, BusinessConstant.ENABLE_YES);
        return queryPageListByQueryWrapper(params, queryWrapper);
    }

    @Override
    public Page<SuggestVO> queryPageListBySubjectType(PageParams<SuggestPageQuery> params) {
        QueryWrapper<Suggest> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Suggest::getProjectId, ContextUtil.getProjectId())
                .eq(Suggest::getSubjectType, ContextUtil.getSubjectType()).eq(Suggest::getUserId, ContextUtil.getUserId())
                .eq(Suggest::getIsDeleted, BusinessConstant.DELETE_NO).eq(Suggest::getIsEnabled, BusinessConstant.ENABLE_YES);
        return queryPageListByQueryWrapper(params, queryWrapper);
    }

    private Page<SuggestVO> queryPageListByQueryWrapper(PageParams<SuggestPageQuery> params, QueryWrapper<Suggest> queryWrapper) {
        Page<SuggestVO> result = ConvertUtil.convertPage(page(params.buildPage(), queryWrapper), SuggestVO.class);
        if (result.getRecords() == null || result.getRecords().isEmpty()) {
            return result;
        }
        // 拼接反馈者名称，姓名+公司名
        List<Long> userIds = result.getRecords().stream().map(SuggestVO::getUserId).collect(Collectors.toList());
        UserAccountDto userAccountDto = new UserAccountDto();
        userAccountDto.setUserIds(userIds);
        R<List<UserAccountVo>> listR = userAccountServiceFeign.querySimpleByIds(userAccountDto);
        if (SUCCESS_CODE == listR.getCode()) {
            List<UserAccountVo> userAccountVos = listR.getData();
            if (userAccountVos != null && !userAccountVos.isEmpty()) {
                Map<Long, UserAccountVo> collect = userAccountVos.stream().collect(Collectors.toMap(UserAccountVo::getId, userAccountVo -> userAccountVo));
                // 拼接 用户姓名 公司名
                result.getRecords().parallelStream().forEach(suggestVO -> {
                    UserAccountVo userAccountVo = collect.get(suggestVO.getUserId());
                    if (userAccountVo == null) {
                        return;
                    }
                    suggestVO.setUserName(userAccountVo.getName());
//                    suggestVO.setCompanyName(StringUtils.isBlank(userAccountVo.getCompanyName()) ? userAccountVo.getCompanyEnName() : userAccountVo.getCompanyName());
                });
            }
        }


        return result;
    }
}
